/* Copyright (C) 2010 Luca Piccinelli
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <opencv2/core/core.hpp>

#include <algorithm>
#include <opencv2/highgui/highgui.hpp>

#include "imgops/functions/img_improvement.h"

using namespace cv;
using namespace std;

namespace NAMESPACE{

struct Vec3bMax{
    bool operator ()(const Vec3b& a, const Vec3b& b){
        return (a[0] < b [0] && a[1] < b[1] && a[2] < b[2]);
    }
};

void white_balance(const cv::Mat& in, cv::Mat& out, WB_METHOD method){
    Vec3b max = *(max_element( in.begin<Vec3b>(), in.end<Vec3b>(), Vec3bMax() ));
    Vec3d scale_vec( (255.0 / max[0]), (255.0 / max[1]), (255.0 / max[2]) );

    Mat tmp_out(in.rows, in.cols, in.type());
    MatConstIterator_<Vec3b> in_it = in.begin<Vec3b>(),
                             end_in_it = in.end<Vec3b>();
    MatIterator_<Vec3b> out_it = tmp_out.begin<Vec3b>();

    for(; in_it != end_in_it; in_it++, out_it++){
        *out_it = Vec3b ( std::min( (*in_it)[0] * scale_vec[0], 255.0 ),
                          std::min( (*in_it)[1] * scale_vec[1], 255.0 ),
                          std::min( (*in_it)[2] * scale_vec[2], 255.0 ) );
    }

    out = tmp_out;
}

}